<?php
if (!defined("APP_PATH")) {
    define('APP_PATH',__DIR__.'/../application/');
    // 加载框架引导文件
    require  __DIR__.'/../thinkphp/start.php';
}

use think\Db;
use think\Exception;
use think\Log;

echo "<pre>";
//每10分钟触发一次
insql();

function insql()
{
    $debug = config("app_debug");
    if (php_sapi_name() != 'cli' && !$debug) {
        echo '只能在cli模式下或者开启调试模式运行：' . date('Y-m-d H:i:s') . "\r\n";die;
    }

    echo '开始执行的时间：'.date('Y-m-d H:i:s')."\r\n";

    $redis = rds();
    $bkey = 'insql';
    if($debug)
        delkey($redis,$bkey);//测试
    $op = $redis->set($bkey,1,['NX','EX'=>550]);
    if(!$op){
        echo '请勿频繁操作：'.date('Y-m-d H:i:s')."\r\n";
        goto END1;
    }

    $where = [
        't.status' => 1,
        't.isout' => 0,
        't.type' => 0,
        'u.credit1'=>['>',0]
    ];
    $orders = \db('user')
        ->alias('u')
        ->join('user_detail ud','u.id = ud.uid')
        ->join('tron_order t','u.id=t.uid')
        ->where($where)
        ->field('u.credit1,u.credit2,u.id as uid,t.id,t.amt,t.max_profit,t.profit,ud.tjstr')
        ->select();
    $user_orders = [];
    $user_profit_sum = [];
    foreach($orders as $order){
        $user_orders[$order['uid']][] = $order;
        $user_profit_sum[$order['uid']] = ($user_profit_sum[$order['uid']]??0)+$order['profit'];
    }
    unset($orders);
//    var_dump($user_orders);
    $all_sy = $redis->hGetAll(REDIS_PREFIX.'user_sy');
    if(empty($all_sy)){
        echo '没有找到新增收益：'.date('Y-m-d H:i:s')."\r\n";
        goto END2;
    }
    $prefix = config('database.prefix');
    $time = time();
    $add_credit2 = '';//会员收益增加
    $dec_credit1 = '';//会员投资额度扣减
    $dec_pv_sum = '';//会员投资额度扣减团队减少业绩
    $dec_pv = '';//会员投资额度扣减团队减少业绩
    $out_oids = '';//出局订单id集合
    $profit_when = '';//订单收益变动
    $dec_user_arr = [];
//    $lua_tzsy = '';//缓存收益和投资变动
//    var_dump($all_sy);
    foreach($all_sy as $user_id=>$syy){
        $lua_tzsy = '';//缓存收益和投资变动
        $uid = substr($user_id,5);
        if($syy>0 && is_numeric($uid) && !empty($user_orders[$uid])){
//            $sy = keeDecimal($syy,6);
            $sy = bcadd($syy,0,6);
            if($sy <= 0) continue;
            $max = $user_orders[$uid][0]['credit1']*2;//目前最大的收益限额
            $out = 0;
            //如果收益超出了可以获得的最大值
            if($max < $user_profit_sum[$uid]+$sy){
                $sy = $max - $user_profit_sum[$uid];
                $out = 1;
            }
//            echo $uid.'----入库:'.$sy."\r\n";

            //新增收益清零---如果结果为负数则为0
            $lua_tzsy .= <<<LUA
            local user_id = KEYS[1]
            local user_sy = KEYS[2]
            local user_tz = KEYS[3]
            local syy = ARGV[1]
            local out = ARGV[2]
            local sy2 = ARGV[3]
            local sy = redis.call('hGet',user_sy,user_id)
            if tonumber(sy) < tonumber(syy) or tonumber(out) > 0
            then
                redis.call('hSet',user_sy,user_id,0)
            else
                redis.call('hIncrByFloat',user_sy,user_id,-sy2)
            end
LUA;
            $KEY_ARGV = [$user_id,REDIS_PREFIX.'user_sy',REDIS_PREFIX.'user_tz',$syy,$out,$sy];
            $KEY_offset = 3;

            $dec_sum = 0;//订单出局 会员所需扣减投资额度
            $profit = $sy;//会员总新增收益
            $ls_oids = '';
            $ls_profits = '';
            foreach($user_orders[$uid] as $user_order){
                if($user_order['max_profit'] <= 0) continue;
                if($user_order['max_profit'] <= $profit + $user_order['profit']){//订单出局
                    $profit -= ($user_order['max_profit'] - $user_order['profit']);
//                    $profit_when .= " when id={$user_order['id']} then {$user_order['max_profit']}";
                    $ls_profits .= " when id={$user_order['id']} then {$user_order['max_profit']}";
                    $ls_oids .= ",{$user_order['id']}";
                    $dec_sum += $user_order['amt'];
                    if($profit == 0) break;
                }else{
//                    if($profit > 0) $profit_when .= " when id={$user_order['id']} then profit+{$profit}";
                    if($profit > 0) $ls_profits .= " when id={$user_order['id']} then profit+{$profit}";
                    break;
                }
            }

            //会员投资额度扣除出局的订单投资额度
            if($dec_sum > 0){
                $tz_balance = array_sum(array_column($user_orders[$uid],'amt')) - $dec_sum;//处理后的投资额度
                if($tz_balance >= 0){
                    //对比执行时投资额度是否异常 如异常则set处理后的投资额度 无异常则扣除本次的投资额度
                    $lua_tzsy .= <<<LUA
                    local tz_balance = ARGV[4]
                    local dec_sum = ARGV[5]
                    local tz = redis.call('hGet',user_tz,user_id)
                    if tz == false or tonumber(tz) < tonumber(dec_sum)
                    then
                        redis.call('hSet',user_tz,user_id,tz_balance)
                    else
                        redis.call('hIncrByFloat',user_tz,user_id,-dec_sum)
                    end
LUA;
                    $KEY_ARGV = array_merge($KEY_ARGV,[$tz_balance,$dec_sum]);
                }
            }

            if($lua_tzsy) $lua_tzsy .= " return true";

            if($lua_tzsy){
                $res = $redis->eval($lua_tzsy,$KEY_ARGV,$KEY_offset);
                if($res === false){
//                    throw new \Exception("Redis+Lua执行失败---缓存收益和投资变动异常");
                    echo $user_id."---入库失败\r\n";
                    continue;
                }
            }

            $add_credit2 .= " when id={$uid} then credit2+{$sy}";
            $out_oids .= $ls_oids;
            $profit_when .= $ls_profits;
            if($dec_sum > 0){
                $dec_credit1 .= " when id={$uid} then credit1-{$dec_sum}";

//                $dec_user_arr[$uid] = $dec_sum;
                $tjstr = $uid.",".$user_orders[$uid][0]['tjstr'];
                $tjstr_arr = explode(',', $tjstr);
                foreach ($tjstr_arr as  $v) {
                    $dec_user_arr[$v] = ($dec_user_arr[$v]??0)+$dec_sum;
//                    if (!empty($dec_user_arr[$v])) {
//                        $dec_user_arr[$v] += $dec_sum;
//                    } else {
//                        $dec_user_arr[$v] = $dec_sum;
//                    }
                }

            }
//            var_dump($add_credit2,$profit_when,$out_oids,$dec_sum,$lua_tzsy);
        }
    }
    unset($all_sy,$user_orders);

    //会员数据入库：会员收益增加 and 会员投资额度扣减
    $u_update = '';
    if($add_credit2){
        $u_update = " credit2=(case {$add_credit2} else credit2 end)";
    }
    if($dec_credit1){
        $u_update .= ",credit1=(case {$dec_credit1} else credit1 end)";
    }
    if ($dec_user_arr) {
//        $user_ids = ;
        $user_ids_str = implode(',',array_keys($dec_user_arr));
        $users_pv = \db('user')->where(['id'=>['in',$user_ids_str]])->column('pv','id');
        foreach ($dec_user_arr as $k => $v) {
            if ($k <= 0) {
                continue;
            }
            $dec_pv_sum .= " when id={$k} then pv_sum-{$v}";
            if ($users_pv[$k]) {
                if ($users_pv[$k] >= $v) {
                    $dec_pv .= " when id={$k} then pv-{$v}";
                } else {
                    $dec_pv .= " when id={$k} then pv-{$users_pv[$k]}";
                }
            }
        }
        unset($dec_user_arr);
        $u_update .= ",pv_sum=(case {$dec_pv_sum} else pv_sum end)";
        $u_update .= ",pv=(case {$dec_pv} else pv end)";
    }

    //订单数据入库：出局订单id集合 and 订单收益变动
    $to_update = '';
    if($out_oids){
        $out_oids = trim($out_oids,',');
        $to_update = " isout=(case when id in ({$out_oids}) then 1 else isout end),outtime=(case when id in ({$out_oids}) then '{$time}' else outtime end)";
    }
    if($profit_when){
        $to_update .= ",profit=(case {$profit_when} else profit end)";
    }

//    if($lua_tzsy) $lua_tzsy .= " return true";
//    var_dump($lua_tzsy);die;
    db::startTrans();
    try {
        if($u_update) \db()->execute("UPDATE {$prefix}user SET ".trim($u_update,','));
        if($to_update) \db()->execute("UPDATE {$prefix}tron_order SET ".trim($to_update,','));
//        if($lua_tzsy){
//            $res = $redis->eval($lua_tzsy);
//            if($res === false){
//                throw new \Exception("Redis+Lua执行失败---缓存收益和投资变动异常");
//            }
//        }
        db::commit();
    }catch (\Exception $e){
        db::rollback();
        Log::error($e->getMessage());
        echo $e->getMessage();
        echo '执行失败：'.date('Y-m-d H:i:s')."\r\n";
    }

    END2:
    delkey($redis,$bkey);
    END1:
    echo '结束执行的时间：'.date('Y-m-d H:i:s')."\r\n";
}


